#
# Wrapper for session handling, CGI stuff that is used by multiple CGI scripts
#
# 2009, Mike Widner <mikewidner@gmail.com>
#
##################

package Fangcheng::CGI;

use 5.006001;
use warnings;
use strict;
use vars qw( @ISA $AUTOLOAD );

use Carp;
use CGI;
use CGI::Session;
use Fangcheng;

my $VERSION = '0.01';
my $STYLESHEET = 'http://localhost/~mwidner/hart/style.css';	# where we store our style sheet
my $HEADER = '/home/mwidner/www/hart/header.html'; # custom HTML header

@ISA = qw( Fangcheng CGI );

# create CGI and Session objects, store internally
sub new {
	my ($class, $title) = @_;
	
	# set up Session management
	my $query = CGI->new();
	my $session = CGI::Session->new( $query ) or croak CGI::Session->errstr;
	
	my $self = {};
	bless $self, ref($class) || $class;
	
	$self->session( $session );
	$self->query( $query );
	
	if ( defined $title ) {
		$self->title( $title );
	}
		
	return( $self );
}

# starts session, checks for expiration; returns session and CGI objects, headers & HTML string to print
sub startPage {
	my ($self) = shift;
	my $pageHeader = $self->session->header();
	$pageHeader .= $self->query->start_html(-title => $self->title, 
										  	-style => {	-src	=> $STYLESHEET }
											);
	
    if ( $self->session->is_expired ) {
		$pageHeader .= $self->query->p("Your session timed out! Refresh the screen to start new session!");
        $pageHeader .= $self->query->end_html();
        croak $pageHeader;		# time to die
	}

    if ( $self->session->is_empty ) {
		$self->session( $self->session->new( $self->query ) );
    }
	
	$pageHeader .= $self->loadSiteHeader();
	
	return( $pageHeader );
}

# because we have to control headers for session management,
# we also have to load the site's stylesheet and header
sub loadSiteHeader {
	my ( $self ) = shift;
	my $str;
	open(HEADER, "<$HEADER") or die "$!";
	while( <HEADER> ) {
		$str .= $_;
	}
	close(HEADER);
	return( $str );
}


# flush the session cache to disk; important for saving state
sub endPage {
	my ( $self ) = shift;
	$self->session->save_param( $self->query() );
	$self->session->flush();
	return( $self->query->end_html() );
}

# checks both session and query for param; if passed value, saves it
sub param {
	my ($self, $param, $value) = @_;
	if (not defined $value) {
		# for some crazy reason we can't just "or" these two
		# it won't work and I'm tired of trying to figure out why
		my $sessVal = $self->session->param($param);
		my $qVal	= $self->query->param($param);
		if (defined $qVal) {
			$value = $qVal;
		}
		elsif (defined $sessVal) {
			$value = $sessVal;
		}
	}
	else {
		$self->session->param( -name => $param, -value => $value );
	}
	return( $value );
}

# clears all saved values, destroys session
sub resetButton {
	my ($self) = shift;
	my $str;
	
	$str = $self->query->p;
	$str .= $self->query->start_form();
	$str .= $self->query->submit(	-name	=> 'RESET',
									-value	=> 'Reset' );
	$str .= $self->query->end_form();
	
	return( $str );
}

sub resetSession {
	my ($self) = shift;
	$self->session->delete();
	$self->session->flush();
	$self->query->delete_all();
}

# delete param value
sub clear {
	my ($self, $param) = @_;
	$self->query->Delete( $param );
	$self->session->clear( $param );
	$self->session->flush();
}

# display an error message
sub error {
	my ($self, $error) = @_;
	
	# Will modify to save state, reload page for correction
	# but works for testing purposes now
	print "$error";
	$self->resetSession();
	$self->cgi->end_html;
	exit(0);
}
1;